home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / vol16n12.zip / ICONED.ZIP / ICON_SRC.ZIP / ICON.PAS < prev    next >
Pascal/Delphi Source File  |  1997-04-10  |  34KB  |  1,351 lines

  1. unit Icon;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  7.   ExtCtrls, StdCtrls, Clipbrd, IconTest;
  8.  
  9. const
  10.   PixelWidth = 8;
  11.   ImageMargin = 12;
  12.   MaxUndo = 19;
  13.   crPencil = 1;
  14.   crFill = 2;
  15.  
  16. type
  17.   T16IconColors = array[0..15] of TRGBQuad;
  18.  
  19.   TDrawingTools = (Capture, Pencil, Fill, Line, ClearRectangle,
  20.                    FilledRectangle, ClearEllipse, FilledEllipse);
  21.  
  22. const
  23.   DefaultColors : T16IconColors =
  24.     ((rgbBlue: $00; rgbGreen: $00; rgbRed: $00; rgbReserved: $00),
  25.      (rgbBlue: $00; rgbGreen: $00; rgbRed: $80; rgbReserved: $00),
  26.      (rgbBlue: $00; rgbGreen: $80; rgbRed: $00; rgbReserved: $00),
  27.      (rgbBlue: $00; rgbGreen: $80; rgbRed: $80; rgbReserved: $00),
  28.      (rgbBlue: $80; rgbGreen: $00; rgbRed: $00; rgbReserved: $00),
  29.      (rgbBlue: $80; rgbGreen: $00; rgbRed: $80; rgbReserved: $00),
  30.      (rgbBlue: $80; rgbGreen: $80; rgbRed: $00; rgbReserved: $00),
  31.      (rgbBlue: $80; rgbGreen: $80; rgbRed: $80; rgbReserved: $00),
  32.      (rgbBlue: $C0; rgbGreen: $C0; rgbRed: $C0; rgbReserved: $00),
  33.      (rgbBlue: $00; rgbGreen: $00; rgbRed: $FF; rgbReserved: $00),
  34.      (rgbBlue: $00; rgbGreen: $FF; rgbRed: $00; rgbReserved: $00),
  35.      (rgbBlue: $00; rgbGreen: $FF; rgbRed: $FF; rgbReserved: $00),
  36.      (rgbBlue: $FF; rgbGreen: $00; rgbRed: $00; rgbReserved: $00),
  37.      (rgbBlue: $FF; rgbGreen: $00; rgbRed: $FF; rgbReserved: $00),
  38.      (rgbBlue: $FF; rgbGreen: $FF; rgbRed: $00; rgbReserved: $00),
  39.      (rgbBlue: $FF; rgbGreen: $FF; rgbRed: $FF; rgbReserved: $00));
  40.  
  41. type
  42.   PIconDir = ^TIconDir;
  43.   TIconDir = record
  44.     idReserved  : word;
  45.     idType      : word;
  46.     idCount     : word;
  47.   end;
  48.  
  49.   PIconDirEntry = ^TIconDirEntry;
  50.   TIconDirEntry = record
  51.     bWidth          : byte;
  52.     bHeight         : byte;
  53.     bColorCount     : byte;
  54.     bReserved       : byte;
  55.     wPlanes         : word;
  56.     wBitCount       : word;
  57.     dwBytesInRes    : dword;
  58.     dwImageOffset   : dword;
  59.   end;
  60.  
  61.   PBitMapInfoHeader = ^TBitMapInfoHeader;
  62.   TBitMapInfoHeader = record
  63.     biSize          : dword;
  64.     biWidth         : longint;
  65.     biHeight        : longint;
  66.     biPlanes        : word;
  67.     biBitCount      : word;
  68.     biCompression   : dword;
  69.     biSizeImage     : dword;
  70.     biXPelsPerMeter : longint;
  71.     biYPelsPerMeter : longint;
  72.     biClrUsed       : dword;
  73.     biClrImportant  : dword;
  74.   end;
  75.  
  76.   TXorMask = array[0..511] of byte;
  77.   TAndMask = array[0..127] of byte;
  78.  
  79.   PIconImage = ^TIconImage;
  80.   TIconImage = record
  81.     icHeader  : TBitMapInfoHeader;
  82.     icColors  : T16IconColors;
  83.     icXOR     : TXorMask;
  84.     icAND     : TAndMask;
  85.   end;
  86.  
  87.   TIconData = record
  88.     XorMask : TXorMask;
  89.     AndMask : TAndMask;
  90.   end;
  91.  
  92.   PGrpIconDirEntry = ^TGrpIconDirEntry;
  93.   TGrpIconDirEntry = record
  94.     bWidth          : byte;
  95.     bHeight         : byte;
  96.     bColorCount     : byte;
  97.     bReserved       : byte;
  98.     wPlanes         : word;
  99.     wBitCount       : word;
  100.     dwBytesInRes    : dword;
  101.     nID             : word;
  102.   end;
  103.  
  104.   TColorTag = 0..2;
  105.  
  106. type
  107.   TIconForm = class(TForm)
  108.     PaintBox: TPaintBox;
  109.     IconImage: TImage;
  110.     ShadowImage: TImage;
  111.     ShadowIcon: TImage;
  112.     WorkingImage: TImage;
  113.     ModifiedLabel: TLabel;
  114.     XLabel: TLabel;
  115.     YLabel: TLabel;
  116.     procedure UpdateCursor;
  117.     procedure AppMessage(var Msg: TMsg; var Handled: Boolean);
  118.     procedure SetupWindow;
  119.     procedure SetupUndoBuff;
  120.     function  LookupColorIndex(ARGBQuadColor : TRGBQuad) : integer;
  121.     function  QuadColorToColor(ARGBQuadColor : TRGBQuad) : TColor;
  122.     function  RGBColorToQuadColor(ARGBColor : TColor) : TRGBQuad;
  123.     function  GetUndoColor(x, y : integer;
  124.       var MaskBit : boolean) : TColor;
  125.     procedure UndoToIcon;
  126.     procedure WorkingToIcon;
  127.     procedure WorkingToUndo;
  128.     procedure UndoToCapturedBuffer;
  129.     procedure CapturedBufferToWorking;
  130.     procedure NextUndo;
  131.     procedure PreviousUndo;
  132.     procedure FormPaint(Sender: TObject);
  133.     procedure SaveIcon(Sender: TObject);
  134.     procedure TestIcon(Sender: TObject);
  135.     procedure CopyCaptured;
  136.     procedure CutCaptured;
  137.     procedure FormCreate(Sender: TObject);
  138.     procedure FormActivate(Sender: TObject);
  139.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  140.     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  141.     procedure FormDestroy(Sender: TObject);
  142.     procedure PaintBoxMouseDown(Sender: TObject; Button: TMouseButton;
  143.       Shift: TShiftState; X, Y: Integer);
  144.     procedure PaintBoxDragOver(Sender, Source: TObject; X, Y: Integer;
  145.       State: TDragState; var Accept: Boolean);
  146.     procedure PaintBoxEndDrag(Sender, Target: TObject; X, Y: Integer);
  147.     procedure PaintBoxMouseMove(Sender: TObject; Shift: TShiftState; X,
  148.       Y: Integer);
  149.     procedure CaptureBegin;
  150.     procedure CapturingDraw;
  151.     procedure CapturedDraw;
  152.     procedure Paste;
  153.     procedure SelectAll;
  154.     procedure PencilDraw;
  155.     procedure FillDraw;
  156.     procedure LineDraw(ACanvas : TCanvas);
  157.     procedure GetRectCorners(var SX, SY, EX, EY : integer);
  158.     procedure RectangleDraw(ACanvas : TCanvas);
  159.     procedure ClearRectangleDraw(ACanvas : TCanvas);
  160.     procedure FilledRectangleDraw(ACanvas : TCanvas);
  161.     procedure EllipseDraw(ACanvas : TCanvas);
  162.     procedure ClearEllipseDraw(ACanvas : TCanvas);
  163.     procedure FilledEllipseDraw(ACanvas : TCanvas);
  164.   private
  165.     { Private declarations }
  166.     UndoIndex : integer;
  167.     UndoBuffer : array[0..MaxUndo] of TIconData;
  168.     StartPos, EndPos, LastPos : TPoint;
  169.     DrawingColor, PixelColor, WorkingColor : TColor;
  170.     DrawingColorIndex : integer;
  171.     ColorTag : TColorTag;
  172.     Modified : boolean;
  173.     Drawn : boolean;
  174.     CapturedOrgStart, CapturedOrgEnd : TPoint;
  175.     CapturedDestStart, CapturedDestEnd : TPoint;
  176.     CapturedDiff : TPoint;
  177.     CapturedBuffer : TIconData;
  178.     Pasted : boolean;
  179.   public
  180.     { Public declarations }
  181.     IconTool : TDrawingTools;
  182.     IconFileName : string;
  183.     IconSize : integer;
  184.     ImageOffset : pchar;
  185.     IconColors : array[0..15] of TRGBQuad;
  186.     F: file;
  187.     IconFileSize : longint;
  188.     IconBuffer : pchar;
  189.     NewIcon : boolean;
  190.     UndoCount : integer;
  191.     Captured, CapturedDragging : boolean;
  192.   end;
  193.  
  194. var
  195.   IconForm: TIconForm;
  196.  
  197. implementation
  198.  
  199. {$R *.DFM}
  200. {$R CURSORS.RES}
  201.  
  202. uses Main;
  203.  
  204.  
  205. procedure TIconForm.UpdateCursor;
  206. begin
  207.   case IconTool of
  208.     Pencil :
  209.     begin
  210.       PaintBox.Cursor:= crPencil;
  211.       PaintBox.DragCursor:= crPencil;
  212.     end;
  213.     Fill :
  214.     begin
  215.       PaintBox.Cursor:= crFill;
  216.       PaintBox.DragCursor:= crFill;
  217.     end;
  218.     Capture, Line..FilledEllipse :
  219.     begin
  220.       PaintBox.Cursor:= crCross;
  221.       PaintBox.DragCursor:= crCross;
  222.     end;
  223.   end;
  224. end;
  225.  
  226. procedure TIconForm.AppMessage(var Msg: TMsg; var Handled: Boolean);
  227. begin
  228.   with Msg do
  229.   if (Message = WM_RBUTTONUP) and
  230.      (PaintBox.Dragging) then
  231.     Message:= WM_LBUTTONUP;
  232. end;
  233.  
  234. procedure TIconForm.SetupWindow;
  235. begin
  236.   with PaintBox do
  237.   begin
  238.     Top:= 1;
  239.     Width:=  IconSize * PixelWidth + 1;
  240.     Height:= IconSize * PixelWidth + 1;
  241.     ShadowImage.Width:= Width;
  242.     ShadowImage.Height:= Height;
  243.   end;
  244.  
  245.   with IconImage do
  246.   begin
  247.     Width:= IconSize;
  248.     Height:= IconSize;
  249.     Left:= PaintBox.Left + PaintBox.Width + ImageMargin;
  250.     Top:= (PaintBox.Height - Height) div 2;
  251.  
  252.     XLabel.Top:= Top + Height + XLabel.Height;
  253.     XLabel.Left:= Left + 4;
  254.     YLabel.Top:= XLabel.Top + XLabel.Height;
  255.     YLabel.Left:= Left + 4;
  256.  
  257.     ModifiedLabel.Top:= YLabel.Top + YLabel.Height * 2;
  258.     ModifiedLabel.Left:= Left + (Width - ModifiedLabel.Width) div 2;
  259.   end;
  260.  
  261.   Width:= IconImage.Left + IconImage.Width +
  262.           GetSystemMetrics(SM_CXSIZEFRAME) +
  263.           ImageMargin;
  264.   Height:= PaintBox.Height +
  265.            GetSystemMetrics(SM_CYSIZEFRAME) * 2 +
  266.            GetSystemMetrics(SM_CYCAPTION);
  267. end;
  268.  
  269. procedure TIconForm.SetupUndoBuff;
  270. var
  271.   PIndex : pchar;
  272. begin
  273.   PIndex:= ImageOffset;
  274.  
  275.   Move(PIconImage(PIndex).icXOR,
  276.        UndoBuffer[UndoIndex].XorMask,
  277.        sizeof(TXorMask));
  278.  
  279.   Move(PIconImage(PIndex).icAND,
  280.        UndoBuffer[UndoIndex].AndMask,
  281.        sizeof(TAndMask));
  282.  
  283.   UndoToIcon;
  284. end;
  285.  
  286. function TIconForm.LookupColorIndex(ARGBQuadColor : TRGBQuad) : integer;
  287. begin
  288.   for Result:= 0 to 15 do
  289.     if dword(IconColors[Result]) =
  290.        dword(ARGBQuadColor) then
  291.       break;
  292. end;
  293.  
  294. function TIconForm.QuadColorToColor(ARGBQuadColor : TRGBQuad) : TColor;
  295. begin
  296.   Result:= RGB(ARGBQuadColor.rgbRed,
  297.                ARGBQuadColor.rgbGreen,
  298.                ARGBQuadColor.rgbBlue);
  299. end;
  300.  
  301. function TIconForm.RGBColorToQuadColor(ARGBColor : TColor) : TRGBQuad;
  302. begin
  303.   Result.rgbRed:=   (ARGBColor and $000000FF);
  304.   Result.rgbGreen:= (ARGBColor and $0000FF00) shr (4 * 2);
  305.   Result.rgbBlue:=  (ARGBColor and $00FF0000) shr (4 * 4);
  306.   Result.rgbReserved:= 0;
  307. end;
  308.  
  309. function TIconForm.GetUndoColor(x, y : integer;
  310.   var MaskBit : boolean) : TColor;
  311. var
  312.   XorIndex, AndIndex : integer;
  313.   ColorNibble : byte;
  314. begin
  315.   XorIndex:= x div 2 + (31 - y) * 16;
  316.   AndIndex:= (31 - y) * 4 + (x shr 3);
  317.  
  318.   if odd(x) then
  319.     ColorNibble:=
  320.       UndoBuffer[UndoIndex].XorMask[XorIndex] and
  321.       $0F
  322.   else
  323.     ColorNibble:=
  324.       UndoBuffer[UndoIndex].XorMask[XorIndex] and
  325.       $F0 shr 4;
  326.  
  327.   MaskBit:= (UndoBuffer[UndoIndex].AndMask[AndIndex]) and
  328.             (1 shl (7 - (x mod 8))) <> 0;
  329.  
  330.   if MaskBit then
  331.     if ColorNibble = 0 then
  332.       Result:= MainForm.TransparentPanel.Color
  333.     else
  334.       Result:= MainForm.ReversePanel.Color
  335.   else
  336.     Result:= RGB(IconColors[ColorNibble].rgbRed,
  337.                  IconColors[ColorNibble].rgbGreen,
  338.                  IconColors[ColorNibble].rgbBlue);
  339. end;
  340.  
  341. procedure TIconForm.UndoToIcon;
  342. var
  343.   x, y : integer;
  344.   MaskBit : boolean;
  345. begin
  346.   for y:= 0 to IconSize - 1 do
  347.     for x:= 0 to IconSize - 1 do
  348.       ShadowIcon.Canvas.Pixels[x, y]:=
  349.         GetUndoColor(x, y, MaskBit);
  350.  
  351.   with ShadowIcon do
  352.   IconImage.Canvas.CopyRect(ClientRect,
  353.                             Canvas,
  354.                             ClientRect);
  355. end;
  356.  
  357. procedure TIconForm.WorkingToIcon;
  358. begin
  359.   with IconImage.Canvas do
  360.   CopyRect(Rect(CapturedDestStart.X,
  361.                 CapturedDestStart.Y,
  362.                 CapturedDestEnd.X + 1,
  363.                 CapturedDestEnd.Y + 1),
  364.                 WorkingImage.Canvas,
  365.            Rect(CapturedOrgStart.X,
  366.                 CapturedOrgStart.Y,
  367.                 CapturedOrgEnd.X + 1,
  368.                 CapturedOrgEnd.Y + 1));
  369. end;
  370.  
  371. procedure TIconForm.WorkingToUndo;
  372. var
  373.   NewColorIndex : integer;
  374.   XorIndex, AndIndex : integer;
  375.   x, y : integer;
  376. begin
  377.   NewColorIndex:= 0;
  378.   case ColorTag of
  379.     0 : NewColorIndex:= DrawingColorIndex;
  380.     1 : NewColorIndex:= 0;
  381.     2 : NewColorIndex:= $F;
  382.   end;
  383.  
  384.   for x:= 0 to IconSize - 1 do
  385.     for y:= 0 to IconSize - 1 do
  386.       if WorkingImage.Canvas.Pixels[x, y] =
  387.          DrawingColor then
  388.       begin
  389.         XorIndex:= x div 2 + (31 - y) * 16;
  390.         AndIndex:= (31 - y) * 4 + (x shr 3);
  391.  
  392.         with UndoBuffer[UndoIndex] do
  393.         begin
  394.           if odd(x) then
  395.             XorMask[XorIndex]:= XorMask[XorIndex] and
  396.             $F0 or
  397.             NewColorIndex
  398.           else
  399.             XorMask[XorIndex]:= XorMask[XorIndex] and
  400.             $0F or
  401.             NewColorIndex shl 4;
  402.  
  403.           if ColorTag = 0 then
  404.             AndMask[AndIndex]:= AndMask[AndIndex] and
  405.             not (1 shl (7 - (x mod 8)))
  406.           else
  407.             AndMask[AndIndex]:= AndMask[AndIndex] or
  408.             (1 shl (7 - (x mod 8)))
  409.         end;
  410.       end;
  411. end;
  412.  
  413. procedure TIconForm.UndoToCapturedBuffer;
  414. begin
  415.   Move(UndoBuffer[UndoIndex].XorMask,
  416.        CapturedBuffer.XorMask,
  417.        sizeof(TXorMask));
  418.  
  419.   Move(UndoBuffer[UndoIndex].AndMask,
  420.        CapturedBuffer.AndMask,
  421.        sizeof(TAndMask));
  422. end;
  423.  
  424. procedure TIconForm.CapturedBufferToWorking;
  425. var
  426.   x, y : integer;
  427.   XorIndex, AndIndex : integer;
  428.   ColorNibble : byte;
  429.   AColor : TColor;
  430. begin
  431.   for y:= CapturedOrgStart.Y to CapturedOrgEnd.Y do
  432.     for x:= CapturedOrgStart.X to CapturedOrgEnd.X do
  433.     begin
  434.       XorIndex:= x div 2 + (31 - y) * 16;
  435.       AndIndex:= (31 - y) * 4 + (x shr 3);
  436.  
  437.       if odd(x) then
  438.         ColorNibble:=
  439.           CapturedBuffer.XorMask[XorIndex] and
  440.           $0F
  441.       else
  442.         ColorNibble:=
  443.           CapturedBuffer.XorMask[XorIndex] and
  444.           $F0 shr 4;
  445.  
  446.       if (CapturedBuffer.AndMask[AndIndex]) and
  447.         (1 shl (7 - (x mod 8))) <> 0 then
  448.         if ColorNibble = 0 then
  449.           AColor:= MainForm.TransparentPanel.Color
  450.         else
  451.           AColor:= MainForm.ReversePanel.Color
  452.       else
  453.         AColor:= RGB(IconColors[ColorNibble].rgbRed,
  454.                      IconColors[ColorNibble].rgbGreen,
  455.                      IconColors[ColorNibble].rgbBlue);
  456.  
  457.       WorkingImage.Canvas.Pixels[x + CapturedDiff.X,
  458.                                  y + CapturedDiff.Y]:=
  459.                                  AColor;
  460.     end;
  461. end;
  462.  
  463. procedure TIconForm.NextUndo;
  464. var
  465.   LastIndex : integer;
  466. begin
  467.   LastIndex:= UndoIndex;
  468.   if UndoCount < MaxUndo then    
  469.     inc(UndoCount);
  470.   if UndoIndex < MaxUndo then
  471.     inc(UndoIndex)
  472.   else
  473.     UndoIndex:= 0;
  474.  
  475.   Move(UndoBuffer[LastIndex].XorMask,
  476.        UndoBuffer[UndoIndex].XorMask,
  477.        sizeof(TXorMask));
  478.  
  479.   Move(UndoBuffer[LastIndex].AndMask,
  480.        UndoBuffer[UndoIndex].AndMask,
  481.        sizeof(TAndMask));
  482. end;
  483.  
  484. procedure TIconForm.PreviousUndo;
  485. begin
  486.   if UndoCount = 0 then exit;
  487.  
  488.   CapturedDraw;
  489.  
  490.   dec(UndoCount);
  491.  
  492.   if UndoIndex > 0 then
  493.     dec(UndoIndex)
  494.   else
  495.     UndoIndex:= MaxUndo;
  496.  
  497.   UndoToIcon;
  498.   FormPaint(Self);
  499. end;
  500.  
  501. procedure TIconForm.FormPaint(Sender: TObject);
  502. var
  503.   i : integer;
  504. begin
  505.   StretchBlt(ShadowImage.Canvas.Handle,
  506.              0,
  507.              0,
  508.              ShadowImage.Width,
  509.              ShadowImage.Height,
  510.              IconImage.Canvas.Handle,
  511.              0,
  512.              0,
  513.              IconImage.Width,
  514.              IconImage.Height,
  515.              SrcCopy);
  516.  
  517.   if MainForm.ShowPixels.Checked then
  518.   with ShadowImage.Canvas do
  519.   begin
  520.     Pen.Color:= clBlack;
  521.     Pen.Style:= psSolid;
  522.     for i:= 0 to IconSize do
  523.     begin
  524.       MoveTo(i * PixelWidth, 0);
  525.       LineTo(i * PixelWidth, IconSize * PixelWidth + 1);
  526.       MoveTo(0, i * PixelWidth);
  527.       LineTo(IconSize * PixelWidth + 1, i * PixelWidth);
  528.     end;
  529.   end;
  530.  
  531.   if Captured then
  532.   with ShadowImage.Canvas do
  533.   begin
  534.     Pen.Color:= clWhite;
  535.     Pen.Style:= psDot;
  536.     Brush.Style:= bsClear;
  537.     Rectangle(CapturedDestStart.X * PixelWidth + 1,
  538.               CapturedDestStart.Y * PixelWidth + 1,
  539.              (CapturedDestEnd.X + 1) * PixelWidth,
  540.              (CapturedDestEnd.Y + 1) * PixelWidth);
  541.   end;
  542.  
  543.   BitBlt(PaintBox.Canvas.Handle,
  544.          0,
  545.          0,
  546.          PaintBox.Width,
  547.          PaintBox.Height,
  548.          ShadowImage.Canvas.Handle,
  549.          0,
  550.          0,
  551.          SrcCopy);
  552.  
  553.   IconImage.Repaint;       
  554. end;
  555.  
  556. procedure TIconForm.SaveIcon(Sender: TObject);
  557. var
  558.   PIndex : pchar;
  559.   NumWritten : longint;
  560. begin
  561.   CapturedDraw;
  562.  
  563.   PIndex:= ImageOffset;
  564.  
  565.   Move(UndoBuffer[UndoIndex].XorMask,
  566.        PIconImage(PIndex).icXOR,
  567.        sizeof(TXorMask));
  568.  
  569.   Move(UndoBuffer[UndoIndex].AndMask,
  570.        PIconImage(PIndex).icAND,
  571.        sizeof(TAndMask));
  572.  
  573.   {$I-}
  574.   AssignFile(F, IconFileName);
  575.   FileMode:= 1;
  576.   Rewrite(F, 1);
  577.   {$I+}
  578.   if IOResult <> 0 then exit;
  579.   BlockWrite(F, IconBuffer^, IconFileSize, NumWritten);
  580.   CloseFile(F);
  581.   Modified:= false;
  582.   ModifiedLabel.Visible:= false;
  583. end;
  584.  
  585. procedure TIconForm.TestIcon(Sender : TObject);
  586. var
  587.   TempIconName : string;
  588.   TempModified : boolean;
  589. begin
  590.   with TIconTestForm.Create(Application) do
  591.   try
  592.     ColorGrid1.ForegroundIndex:= MainForm.TestColorIndex;
  593.     Caption:= ExtractFileName(IconFileName) + ' Test';
  594.     TempIconName:= IconFileName;
  595.     TempModified:= Modified;
  596.     IconFileName:= MainForm.TempIconFile;
  597.     SaveIcon(Sender);
  598.     TestImage.Picture.LoadFromFile(IconFileName);
  599.     ShowModal;
  600.     MainForm.TestColorIndex:= ColorGrid1.ForegroundIndex;
  601.     DeleteFile(IconFileName);
  602.     IconFileName:= TempIconName;
  603.     Modified:= TempModified;
  604.   finally
  605.     Free;
  606.   end;
  607. end;
  608.  
  609. procedure TIconForm.CopyCaptured;
  610. var
  611.   hClipGlobal : THandle;
  612.   PClipIcon, PIndex : pchar;
  613.   ClipSize, CapturedLine : integer;
  614.   CapturedWidth, CapturedHeight : integer;
  615.   CapturedX, CapturedY, LineX : integer;
  616.   y, i : integer;
  617.   TempLine : array[0..15] of byte;
  618. begin
  619.   if (not CapturedDragging) and
  620.      (not Pasted) then
  621.     UndoToCapturedBuffer;
  622.  
  623.   ClipSize:= sizeof(TIconImage) - sizeof(TAndMask);
  624.   hClipGlobal:= GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE,
  625.                             ClipSize);
  626.   if hClipGlobal = 0 then
  627.     exit;
  628.  
  629.   PClipIcon:= GlobalLock(hClipGlobal);
  630.  
  631.   if not OpenClipboard(Handle) then
  632.   begin
  633.     GlobalUnlock(hClipGlobal);
  634.     exit;
  635.   end;
  636.  
  637.   CapturedWidth:= CapturedOrgEnd.X - CapturedOrgStart.X + 1;
  638.   CapturedHeight:= CapturedOrgEnd.Y - CapturedOrgStart.Y + 1;
  639.   CapturedLine:= (CapturedWidth * 4 + 31) div 32 * 4;
  640.  
  641.   PIndex:= @PClipIcon[0];
  642.   FillChar(PIconImage(PIndex).icHeader,
  643.            sizeof(PIconImage(PIndex).icHeader),
  644.            0);
  645.   PIconImage(PIndex).icHeader.biSize:= sizeof(TBitMapInfoHeader);
  646.   PIconImage(PIndex).icHeader.biWidth:= CapturedWidth;
  647.   PIconImage(PIndex).icHeader.biHeight:= CapturedHeight;
  648.   PIconImage(PIndex).icHeader.biPlanes:= 1;
  649.   PIconImage(PIndex).icHeader.biBitCount:= 4;
  650.   PIconImage(PIndex).icHeader.bisizeimage:=
  651.     CapturedLine * CapturedHeight;
  652.  
  653.   Move(DefaultColors,
  654.        PIconImage(PIndex).icColors,
  655.        16 * sizeof(TRGBQuad));
  656.  
  657.   PIndex:= @PClipIcon[sizeof(TBitmapInfoHeader) +
  658.                       sizeof(T16IconColors)];
  659.  
  660.   CapturedX:= CapturedOrgStart.X div 2;
  661.   CapturedY:= 32 - CapturedOrgStart.Y - CapturedHeight;
  662.   for y:= 0 to CapturedHeight - 1 do
  663.   begin
  664.     LineX:= CapturedX + (CapturedY + y) * 16;
  665.     Move(CapturedBuffer.XorMask[LineX], TempLine, CapturedLine);
  666.     if odd(CapturedOrgStart.X) then
  667.     begin
  668.       for i:= 0 to CapturedWidth - 1 do
  669.       TempLine[i]:= ((TempLine[i] and $0F) shl 4) or
  670.                     ((TempLine[i + 1] and $F0) shr 4);
  671.     end;
  672.     Move(TempLine, PIndex[y * CapturedLine], CapturedLine);
  673.   end;
  674.  
  675.   EmptyClipboard;
  676.   SetClipboardData(CF_DIB, hClipGlobal);
  677.   CloseClipboard;
  678.   GlobalUnlock(hClipGlobal);
  679. end;
  680.  
  681. procedure TIconForm.CutCaptured;
  682. var
  683.   x, y : integer;
  684.   XorIndex, AndIndex : integer;
  685. begin
  686.   CopyCaptured;
  687.  
  688.   NextUndo;
  689.  
  690.   for y:= CapturedDestStart.Y to CapturedDestEnd.Y do
  691.     for x:= CapturedDestStart.X to CapturedDestEnd.X do
  692.     begin
  693.       XorIndex:= x div 2 + (31 - y) * 16;
  694.       AndIndex:= (31 - y) * 4 + (x shr 3);
  695.  
  696.       with UndoBuffer[UndoIndex] do
  697.       begin
  698.         if odd(x) then
  699.           XorMask[XorIndex]:= XorMask[XorIndex] and
  700.           $F0
  701.         else
  702.           XorMask[XorIndex]:= XorMask[XorIndex] and
  703.           $0F;
  704.  
  705.         AndMask[AndIndex]:= AndMask[AndIndex] or
  706.           (1 shl (7 - (x mod 8)));
  707.       end;
  708.     end;
  709.  
  710.   UndoToIcon;
  711.  
  712.   Captured:= false;
  713.   CapturedDragging:= false;
  714.   Pasted:= false;
  715.   UpdateCursor;
  716.  
  717.   FormPaint(Self);
  718. end;
  719.  
  720. procedure TIconForm.FormCreate(Sender: TObject);
  721. begin
  722.   Application.OnMessage:= AppMessage;
  723.   Screen.Cursors[crSize]:= LoadCursor(hInstance, 'GRABHAND');
  724.   Screen.Cursors[crPencil]:= LoadCursor(hInstance, 'PENCIL');
  725.   Screen.Cursors[crFill]:= LoadCursor(hInstance, 'FILL');
  726.   IconTool:= Pencil;
  727.   UpdateCursor;
  728. end;
  729.  
  730. procedure TIconForm.FormActivate(Sender: TObject);
  731. begin
  732.   with MainForm do
  733.   begin
  734.     DrawingTool:= IconTool;
  735.     UpdateTool;
  736.   end;
  737. end;
  738.  
  739. procedure TIconForm.FormClose(Sender: TObject; var Action: TCloseAction);
  740. begin
  741.   Action:= caFree;
  742. end;
  743.  
  744. procedure TIconForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  745. var
  746.   i : integer;
  747. begin
  748.   if Modified then
  749.   begin
  750.     BringToFront;
  751.  
  752.     i:= MessageDlg('Save changes to ' + IconFileName,
  753.       mtConfirmation, [mbYes, mbNo, mbCancel], 0);
  754.  
  755.     if i = mrYes then
  756.       SaveIcon(Sender);
  757.  
  758.     if i = mrCancel then
  759.       CanClose:= false;
  760.   end;
  761. end;
  762.  
  763. procedure TIconForm.FormDestroy(Sender: TObject);
  764. begin
  765.   if assigned(IconBuffer) then
  766.     FreeMem(IconBuffer, IconFileSize);
  767. end;
  768.  
  769. procedure TIconForm.PaintBoxMouseDown(Sender: TObject;
  770.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  771. var
  772.   AX, AY : integer;
  773.   RGBQuadDrawingColor, RGBQuadPixelColor : TRGBQuad;
  774.   WorkingColorIndex : integer;
  775.   FillColorIndex : integer;
  776.   FillColor : TColor;
  777.   PixelMaskBit, ColorMaskBit : boolean;
  778. begin
  779.   case Button of
  780.     mbLeft :
  781.     begin
  782.       DrawingColor:= MainForm.LeftButtonPanel.Color;
  783.       ColorTag:= MainForm.LeftButtonPanel.Tag;
  784.     end;
  785.     mbRight :
  786.     begin
  787.       DrawingColor:= MainForm.RightButtonPanel.Color;
  788.       ColorTag:= MainForm.RightButtonPanel.Tag;
  789.     end;
  790.     mbMiddle : exit;
  791.   end;
  792.  
  793.   AX:= X;
  794.   AY:= Y;
  795.   StartPos.X:= (AX - 1) div PixelWidth;
  796.   StartPos.Y:= (AY - 1) div PixelWidth;
  797.   EndPos.X:= StartPos.X;
  798.   EndPos.Y:= StartPos.Y;
  799.   LastPos.X:= StartPos.X;
  800.   LastPos.Y:= StartPos.Y;
  801.  
  802.   if IconTool <> Capture then
  803.   begin
  804.     RGBQuadDrawingColor:= RGBColorToQuadColor(
  805.                           ColorToRGB(DrawingColor));
  806.  
  807.     DrawingColorIndex:= LookupColorIndex(RGBQuadDrawingColor);
  808.  
  809.     PixelColor:= GetUndoColor(StartPos.X, StartPos.Y, PixelMaskBit);
  810.  
  811.     RGBQuadPixelColor:= RGBColorToQuadColor(
  812.                         ColorToRGB(PixelColor));
  813.  
  814.     for FillColorIndex:= 0 to 15 do
  815.       if (dword(IconColors[FillColorIndex]) <>
  816.           dword(RGBQuadDrawingColor)) and
  817.          (dword(IconColors[FillColorIndex]) <>
  818.           dword(RGBQuadPixelColor)) then
  819.        break;
  820.  
  821.     FillColor:= QuadColorToColor(IconColors[FillColorIndex]);
  822.  
  823.     with WorkingImage.Canvas do
  824.     begin
  825.       Brush.Color:= FillColor;
  826.       FillRect(ClientRect);
  827.     end;
  828.  
  829.     if IconTool = Fill then
  830.     begin
  831.       for WorkingColorIndex:= 0 to 15 do
  832.         if (dword(IconColors[WorkingColorIndex]) <>
  833.             dword(RGBQuadDrawingColor)) and
  834.            (dword(IconColors[WorkingColorIndex]) <>
  835.             dword(RGBQuadPixelColor)) and
  836.            (FillColorIndex <>
  837.             WorkingColorIndex) then
  838.         break;
  839.  
  840.       WorkingColor:= QuadColorToColor(IconColors[WorkingColorIndex]);
  841.  
  842.       for AY:= 0 to IconSize - 1 do
  843.         for AX:= 0 to IconSize - 1 do
  844.           if (GetUndoColor(AX, AY, ColorMaskBit) = PixelColor) and
  845.              (ColorMaskBit = PixelMaskBit) then
  846.             WorkingImage.Canvas.Pixels[AX, AY]:= WorkingColor;
  847.     end;
  848.   end;
  849.  
  850.   case IconTool of
  851.     Capture : CaptureBegin;
  852.     Pencil  : PencilDraw;
  853.     Fill    : FillDraw;
  854.   end;
  855.  
  856.   if IconTool <> Fill then
  857.     PaintBox.BeginDrag(false);
  858.  
  859.   FormPaint(Sender);
  860. end;
  861.  
  862. procedure TIconForm.PaintBoxDragOver(Sender, Source: TObject; X,
  863.   Y: Integer; State: TDragState; var Accept: Boolean);
  864. var
  865.   AX, AY : integer;
  866. begin
  867.   AX:= (X - 1) div PixelWidth;
  868.   AY:= (Y - 1) div PixelWidth;
  869.   XLabel.Caption:= 'X: ' + IntToStr(AX);
  870.   YLabel.Caption:= 'Y: ' + IntToStr(AY);
  871.   EndPos.X:= AX;
  872.   EndPos.Y:= AY;
  873.  
  874.   if (EndPos.X = LastPos.X) and
  875.      (EndPos.Y = LastPos.Y) then
  876.     exit;
  877.  
  878.   if (IconTool <> Pencil) and
  879.      (IconTool <> Capture) then
  880.     UndoToIcon;
  881.  
  882.   with IconImage do
  883.   case IconTool of
  884.     Capture         : CapturingDraw;
  885.     Pencil          : PencilDraw;
  886.     Fill            : exit;
  887.     ClearRectangle  : ClearRectangleDraw(Canvas);
  888.     FilledRectangle : FilledRectangleDraw(Canvas);
  889.     ClearEllipse    : ClearEllipseDraw(Canvas);
  890.     FilledEllipse   : FilledEllipseDraw(Canvas);
  891.     Line            : LineDraw(Canvas);
  892.   end;
  893.  
  894.   if IconTool <> Capture then
  895.   begin
  896.     Modified:= true;
  897.     ModifiedLabel.Visible:= true;
  898.     Drawn:= true;
  899.   end;
  900.  
  901.   LastPos.X:= EndPos.X;
  902.   LastPos.Y:= EndPos.Y;
  903.  
  904.   FormPaint(Sender);
  905. end;
  906.  
  907. procedure TIconForm.PaintBoxEndDrag(Sender, Target: TObject;
  908.   X, Y: Integer);
  909. begin
  910.   if not Drawn then exit;
  911.   Drawn:= false;
  912.  
  913.   with WorkingImage do
  914.   case IconTool of
  915.     Capture         : exit;
  916.     Pencil          : ;
  917.     Fill            : exit;
  918.     ClearRectangle  : ClearRectangleDraw(Canvas);
  919.     FilledRectangle : FilledRectangleDraw(Canvas);
  920.     ClearEllipse    : ClearEllipseDraw(Canvas);
  921.     FilledEllipse   : FilledEllipseDraw(Canvas);
  922.     Line            : LineDraw(Canvas);
  923.   end;
  924.  
  925.   NextUndo;
  926.   WorkingToUndo;
  927.   UndoToIcon;
  928.  
  929.   FormPaint(Sender);
  930. end;
  931.  
  932. procedure TIconForm.PaintBoxMouseMove(Sender: TObject; Shift: TShiftState;
  933.   X, Y: Integer);
  934. var
  935.   AX, AY : integer;
  936. begin
  937.   AX:= (X - 1) div PixelWidth;
  938.   AY:= (Y - 1) div PixelWidth;
  939.   XLabel.Caption:= 'X: ' + IntToStr(AX);
  940.   YLabel.Caption:= 'Y: ' + IntToStr(AY);
  941.  
  942.   if (Captured) and
  943.      (AX >= CapturedDestStart.X) and
  944.      (AX <= CapturedDestEnd.X) and
  945.      (AY >= CapturedDestStart.Y) and
  946.      (AY <= CapturedDestEnd.Y) then
  947.     PaintBox.Cursor:= crSize
  948.   else
  949.     UpdateCursor;
  950. end;
  951.  
  952. procedure TIconForm.CaptureBegin;
  953. begin
  954.   if not Captured then exit;
  955.   if (StartPos.X >= CapturedDestStart.X) and
  956.      (EndPos.X <= CapturedDestEnd.X) and
  957.      (StartPos.Y >= CapturedDestStart.Y) and
  958.      (EndPos.Y <= CapturedDestEnd.Y) then
  959.   begin
  960.     if (not CapturedDragging) and
  961.        (not Pasted) then
  962.       begin
  963.         UndoToCapturedBuffer;
  964.         CapturedBufferToWorking;
  965.       end;
  966.     CapturedDragging:= true;
  967.     PaintBox.DragCursor:= crSize;
  968.   end
  969.   else
  970.     CapturedDraw;
  971. end;
  972.  
  973. procedure TIconForm.CapturingDraw;
  974. begin
  975.   if CapturedDragging then
  976.   begin
  977.     if (StartPos.X = EndPos.X) and
  978.        (StartPos.Y = EndPos.Y) then
  979.       exit;
  980.  
  981.     CapturedDiff.X:= CapturedDiff.X + EndPos.X - LastPos.X;
  982.     CapturedDiff.Y:= CapturedDiff.Y + EndPos.Y - LastPos.Y;
  983.  
  984.     CapturedDestStart.X:= CapturedOrgStart.X + CapturedDiff.X;
  985.     CapturedDestStart.Y:= CapturedOrgStart.Y + CapturedDiff.Y;
  986.     CapturedDestEnd.X:= CapturedOrgEnd.X + CapturedDiff.X;
  987.     CapturedDestEnd.Y:= CapturedOrgEnd.Y + CapturedDiff.Y;
  988.  
  989.     UndoToIcon; 
  990.     WorkingToIcon;
  991.   end
  992.   else
  993.   begin
  994.     if (StartPos.X = EndPos.X) or
  995.        (StartPos.Y = EndPos.Y) then
  996.     begin
  997.       Captured:= false;
  998.       exit;
  999.     end;
  1000.  
  1001.     if StartPos.X < EndPos.X then
  1002.     begin
  1003.       CapturedOrgStart.X:= StartPos.X;
  1004.       CapturedOrgEnd.X:= EndPos.X;
  1005.     end
  1006.     else
  1007.     begin
  1008.       CapturedOrgStart.X:= EndPos.X;
  1009.       CapturedOrgEnd.X:= StartPos.X;
  1010.     end;
  1011.  
  1012.     if StartPos.Y < EndPos.Y then
  1013.     begin
  1014.       CapturedOrgStart.Y:= StartPos.Y;
  1015.       CapturedOrgEnd.Y:= EndPos.Y;
  1016.     end
  1017.     else
  1018.     begin
  1019.       CapturedOrgStart.Y:= EndPos.Y;
  1020.       CapturedOrgEnd.Y:= StartPos.Y;
  1021.     end;
  1022.  
  1023.     CapturedDestStart.X:= CapturedOrgStart.X;
  1024.     CapturedDestStart.Y:= CapturedOrgStart.Y;
  1025.     CapturedDestEnd.X:= CapturedOrgEnd.X;
  1026.     CapturedDestEnd.Y:= CapturedOrgEnd.Y;
  1027.  
  1028.     CapturedDiff.X:= 0;
  1029.     CapturedDiff.Y:= 0;
  1030.  
  1031.     Captured:= true;
  1032.   end;
  1033. end;
  1034.  
  1035. procedure TIconForm.CapturedDraw;
  1036. var
  1037.   x, y : integer;
  1038.   Dest : TPoint;
  1039.   XorIndex, AndIndex : integer;
  1040.   ColorNibble, AndBit : integer;
  1041. begin
  1042.   if not Captured then exit;
  1043.  
  1044.   UpdateCursor;
  1045.   Captured:= false;
  1046.   CapturedDragging:= false;
  1047.  
  1048.   FormPaint(Self);
  1049.  
  1050.   if (CapturedDiff.X = 0) and
  1051.      (CapturedDiff.Y = 0) and
  1052.      (not Pasted) then
  1053.     exit;
  1054.  
  1055.   Pasted:= false;
  1056.  
  1057.   NextUndo;
  1058.  
  1059.   Modified:= true;
  1060.   ModifiedLabel.Visible:= true;
  1061.  
  1062.   for y:= CapturedOrgStart.Y to CapturedOrgEnd.Y do
  1063.     for x:= CapturedOrgStart.X to CapturedOrgEnd.X do
  1064.     begin
  1065.       Dest.X:= x + CapturedDiff.X;
  1066.       Dest.Y:= y + CapturedDiff.Y;
  1067.  
  1068.       if (Dest.X < 0) or
  1069.          (Dest.X > IconSize - 1) or
  1070.          (Dest.Y < 0) or
  1071.          (Dest.Y > IconSize - 1) then
  1072.         continue;
  1073.  
  1074.       XorIndex:= x div 2 + (31 - y) * 16;
  1075.       AndIndex:= (31 - y) * 4 + (x shr 3);
  1076.  
  1077.       if odd(x) then
  1078.         ColorNibble:=
  1079.           CapturedBuffer.XorMask[XorIndex] and
  1080.       $0F
  1081.       else
  1082.         ColorNibble:=
  1083.           CapturedBuffer.XorMask[XorIndex] and
  1084.       $F0 shr 4;
  1085.  
  1086.       AndBit:= CapturedBuffer.AndMask[AndIndex] and
  1087.         (1 shl (7 - (x mod 8)));
  1088.  
  1089.       XorIndex:= Dest.X div 2 + (31 - Dest.Y) * 16;
  1090.       AndIndex:= (31 - Dest.Y) * 4 + (Dest.X shr 3);
  1091.  
  1092.       with UndoBuffer[UndoIndex] do
  1093.       begin
  1094.         if odd(Dest.X) then
  1095.           XorMask[XorIndex]:= XorMask[XorIndex] and
  1096.           $F0 or
  1097.           ColorNibble
  1098.         else
  1099.           XorMask[XorIndex]:= XorMask[XorIndex] and
  1100.           $0F or
  1101.           ColorNibble shl 4;
  1102.  
  1103.         if AndBit = 0 then
  1104.           AndMask[AndIndex]:= AndMask[AndIndex] and
  1105.           not (1 shl (7 - (Dest.X mod 8)))
  1106.         else
  1107.           AndMask[AndIndex]:= AndMask[AndIndex] or
  1108.           (1 shl (7 - (Dest.X mod 8)))
  1109.       end;
  1110.     end;
  1111.  
  1112.   FormPaint(Self);
  1113. end;
  1114.  
  1115. procedure TIconForm.Paste;
  1116. var
  1117.   hClipGlobal : THandle;
  1118.   PClipIcon, PIndex : pchar;
  1119.   ClipWidth, ClipHeight : integer;
  1120.   ClipLine : integer;
  1121.   y : integer;
  1122. begin
  1123.   CapturedDraw;
  1124.   if not Clipboard.HasFormat(CF_DIB) then exit;
  1125.   if not OpenClipboard(Handle) then exit;
  1126.  
  1127.   hClipGlobal:= GetClipboardData(CF_DIB);
  1128.   PClipIcon:= GlobalLock(hClipGlobal);
  1129.   if (hClipGlobal = 0) or
  1130.      (PClipIcon = nil) then
  1131.   begin
  1132.     CloseClipboard;
  1133.     ShowMessage('Paste failed');
  1134.     exit;
  1135.   end;
  1136.  
  1137.   PIndex:= @PClipIcon[0];
  1138.   ClipWidth:=  PBitMapInfoHeader(PIndex).biWidth;
  1139.   ClipHeight:= PBitMapInfoHeader(PIndex).biHeight;
  1140.   if (ClipWidth = 0) or
  1141.      (ClipWidth > 32) or
  1142.      (ClipHeight <= 0) or
  1143.      (ClipHeight > 32) or
  1144.      (PBitMapInfoHeader(PIndex).biPlanes <> 1) or
  1145.      (PBitMapInfoHeader(PIndex).biBitCount <> 4) or
  1146.      (PBitMapInfoHeader(PIndex).biCompression <> 0) then
  1147.   begin
  1148.     CloseClipboard;
  1149.     ShowMessage('Bitmap format or size not supported');
  1150.     exit;
  1151.   end;
  1152.  
  1153.   PIndex:= @PClipIcon[PBitMapInfoHeader(PClipIcon).biSize +
  1154.                       sizeof(T16IconColors)];
  1155.  
  1156.   ClipLine:= (ClipWidth * 4 + 31) div 32 * 4;
  1157.   for y:= 0 to ClipHeight - 1 do
  1158.     Move(PIndex[y * ClipLine],
  1159.          CapturedBuffer.XorMask[(32 - ClipHeight + y) * 16],
  1160.          ClipLine);
  1161.  
  1162.   FillChar(CapturedBuffer.AndMask,
  1163.            sizeof(TAndMask),
  1164.            0);
  1165.  
  1166.   CapturedOrgStart.X:= 0;
  1167.   CapturedOrgStart.Y:= 0;
  1168.   CapturedOrgEnd.X:= ClipWidth - 1;
  1169.   CapturedOrgEnd.Y:= ClipHeight - 1;
  1170.   CapturedDestStart.X:= CapturedOrgStart.X;
  1171.   CapturedDestStart.Y:= CapturedOrgStart.Y;
  1172.   CapturedDestEnd.X:= CapturedOrgEnd.X;
  1173.   CapturedDestEnd.Y:= CapturedOrgEnd.Y;
  1174.  
  1175.   CapturedDiff.X:= 0;
  1176.   CapturedDiff.Y:= 0;
  1177.  
  1178.   CapturedBufferToWorking;
  1179.   WorkingToIcon;
  1180.  
  1181.   Captured:= true;
  1182.   Pasted:= true;
  1183.  
  1184.   IconTool:= Capture;
  1185.   with MainForm do
  1186.   begin
  1187.     DrawingTool:= IconTool;
  1188.     UpdateTool;
  1189.   end;
  1190.  
  1191.   GlobalUnlock(hClipGlobal);
  1192.   CloseClipboard;
  1193.  
  1194.   Modified:= true;
  1195.   ModifiedLabel.Visible:= true;
  1196.  
  1197.   FormPaint(Self);
  1198. end;
  1199.  
  1200. procedure TIconForm.SelectAll;
  1201. begin
  1202.   CapturedDraw;
  1203.  
  1204.   CapturedOrgStart.X:= 0;
  1205.   CapturedOrgStart.Y:= 0;
  1206.   CapturedOrgEnd.X:= 31;
  1207.   CapturedOrgEnd.Y:= 31;
  1208.  
  1209.   CapturedDestStart.X:= 0;
  1210.   CapturedDestStart.Y:= 0;
  1211.   CapturedDestEnd.X:= 31;
  1212.   CapturedDestEnd.Y:= 31;
  1213.  
  1214.   CapturedDiff.X:= 0;
  1215.   CapturedDiff.Y:= 0;
  1216.  
  1217.   Captured:= true;
  1218.  
  1219.   IconTool:= Capture;  
  1220.   with MainForm do
  1221.   begin
  1222.     DrawingTool:= IconTool;
  1223.     UpdateTool;
  1224.   end;
  1225.  
  1226.   FormPaint(Self);
  1227. end;
  1228.  
  1229. procedure TIconForm.PencilDraw;
  1230. begin
  1231.   with WorkingImage.Canvas do
  1232.   begin
  1233.     Pen.Color:= DrawingColor;
  1234.     MoveTo(LastPos.X, LastPos.Y);
  1235.     LineTo(EndPos.X, EndPos.Y);
  1236.     Pixels[EndPos.X, EndPos.Y]:= DrawingColor;
  1237.   end;
  1238.  
  1239.   with IconImage.Canvas do
  1240.   begin
  1241.     Pen.Color:= DrawingColor;
  1242.     MoveTo(LastPos.X, LastPos.Y);
  1243.     LineTo(EndPos.X, EndPos.Y);
  1244.     Pixels[EndPos.X, EndPos.Y]:= DrawingColor;
  1245.   end;
  1246.  
  1247.   Modified:= true;
  1248.   ModifiedLabel.Visible:= true;
  1249.   Drawn:= true;
  1250. end;
  1251.  
  1252. procedure TIconForm.FillDraw;
  1253. begin
  1254.   with WorkingImage.Canvas do
  1255.   begin
  1256.     Brush.Color:= DrawingColor;
  1257.     FloodFill(EndPos.X, EndPos.Y, WorkingColor, fsSurface);
  1258.   end;
  1259.  
  1260.   Modified:= true;
  1261.   ModifiedLabel.Visible:= true;
  1262.  
  1263.   NextUndo;
  1264.   WorkingToUndo;
  1265.   UndoToIcon;
  1266.  
  1267.   FormPaint(Self);
  1268. end;
  1269.  
  1270. procedure TIconForm.LineDraw(ACanvas : TCanvas);
  1271. begin
  1272.   with ACanvas do
  1273.   begin
  1274.     Pen.Color:= DrawingColor;
  1275.     MoveTo(StartPos.X, StartPos.Y);
  1276.     LineTo(EndPos.X, EndPos.Y);
  1277.     Pixels[EndPos.X, EndPos.Y]:= DrawingColor;
  1278.   end;
  1279. end;
  1280.  
  1281. procedure TIconForm.GetRectCorners(var SX, SY, EX, EY : integer);
  1282. begin
  1283.   SX:= StartPos.X;
  1284.   SY:= StartPos.Y;
  1285.   EX:= EndPos.X;
  1286.   EY:= EndPos.Y;
  1287.  
  1288.   if SX > EX then
  1289.     inc(SX)
  1290.   else
  1291.     if EX > SX then
  1292.       inc(EX);
  1293.  
  1294.   if SY > EY then
  1295.     inc(SY)
  1296.   else
  1297.     if EY > SY then
  1298.       inc(EY);
  1299. end;
  1300.  
  1301. procedure TIconForm.RectangleDraw(ACanvas : TCanvas);
  1302. var
  1303.   SX, SY, EX, EY : integer;
  1304. begin
  1305.   GetRectCorners(SX, SY, EX, EY);
  1306.   with ACanvas do
  1307.   begin
  1308.     Pen.Color:= DrawingColor;
  1309.     Rectangle(SX, SY, EX, EY);
  1310.   end;
  1311. end;
  1312.  
  1313. procedure TIconForm.ClearRectangleDraw(ACanvas : TCanvas);
  1314. begin
  1315.   ACanvas.Brush.Style:= bsClear;
  1316.   RectangleDraw(ACanvas);
  1317. end;
  1318.  
  1319. procedure TIconForm.FilledRectangleDraw(ACanvas : TCanvas);
  1320. begin
  1321.   ACanvas.Brush.Color:= DrawingColor;
  1322.   RectangleDraw(ACanvas);
  1323. end;
  1324.  
  1325. procedure TIconForm.EllipseDraw(ACanvas : TCanvas);
  1326. var
  1327.   SX, SY, EX, EY : integer;
  1328. begin
  1329.   GetRectCorners(SX, SY, EX, EY);
  1330.   with ACanvas do
  1331.   begin
  1332.     Pen.Color:= DrawingColor;
  1333.     Ellipse(SX, SY, EX, EY);
  1334.   end;
  1335. end;
  1336.  
  1337. procedure TIconForm.ClearEllipseDraw(ACanvas : TCanvas);
  1338. begin
  1339.   ACanvas.Brush.Style:= bsClear;
  1340.   EllipseDraw(ACanvas);
  1341. end;
  1342.  
  1343. procedure TIconForm.FilledEllipseDraw(ACanvas : TCanvas);
  1344. begin
  1345.   ACanvas.Brush.Color:= DrawingColor;
  1346.   EllipseDraw(ACanvas);
  1347. end;
  1348.  
  1349.  
  1350. end.
  1351.